import com.ww.exercise.channel.actualcombat.producerconsumer.ChannelProcessor
import com.ww.exercise.channel.actualcombat.producerconsumer.Config
import com.ww.exercise.channel.actualcombat.producerconsumer.ShutdownResult
import kotlinx.coroutines.*
import java.util.concurrent.atomic.AtomicLong
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds

/**
 * 毁灭级极限测试 - 专为发现隐藏bug设计
 */
class DestructionLevelTester {

    /**
     * 测试1: 内存爆炸测试 - 创建海量对象耗尽内存
     */
    suspend fun testMemoryApocalypse(): ApocalypseTestResult {
        println("=== 💥 内存爆炸测试 ===")

        // 使用超大对象
        data class MemoryHog(val id: Long, val data: ByteArray = ByteArray(1024 * 1024)) // 1MB对象

        val processor = ChannelProcessor<MemoryHog>(
            config = Config(
                channelCapacity = 10000, // 超大容量
                consumerCount = 2,
                shutdownTimeout = 120.seconds
            )
        )

        val oomCounter = AtomicLong(0)
        val producedBeforeOOM = AtomicLong(0)

        // 消费者：故意慢速处理，积累内存压力
        processor.startConsumers { item ->
            delay(1000) // 很慢的处理，让对象在内存中堆积
            // 故意不释放引用，模拟内存泄漏
        }

        val startTime = System.currentTimeMillis()

        try {
            // 疯狂生产，直到OOM或达到极限
            val producerJob = GlobalScope.launch {
                var counter = 0L
                try {
                    while (counter < 1_000_000) { // 尝试生产100万个1MB对象 -> 1TB内存！
                        if (processor.produce(MemoryHog(counter))) {
                            counter++
                            producedBeforeOOM.set(counter)

                            if (counter % 1000 == 0L) {
                                val runtime = Runtime.getRuntime()
                                val usedMB = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024)
                                val maxMB = runtime.maxMemory() / (1024 * 1024)
                                println("内存压力: ${usedMB}MB / ${maxMB}MB, 生产了 $counter 个对象")

                                // 强制GC，看是否能缓解
                                System.gc()
                            }
                        } else {
                            break
                        }
                    }
                } catch (e: OutOfMemoryError) {
                    oomCounter.incrementAndGet()
                    println("💥 内存溢出! 在生产 $counter 个对象时发生")
                }
            }

            producerJob.join()
        } catch (e: OutOfMemoryError) {
            oomCounter.incrementAndGet()
            println("💥 测试过程中发生内存溢出")
        }

        delay(5000) // 给系统一些恢复时间

        val shutdownResult = processor.shutdown()
        val duration = System.currentTimeMillis() - startTime

        return ApocalypseTestResult(
            testName = "内存爆炸测试",
            producedBeforeCrash = producedBeforeOOM.get(),
            oomCount = oomCounter.get(),
            duration = duration,
            shutdownResult = shutdownResult,
            survived = oomCounter.get() == 0L
        )
    }

    /**
     * 测试2: 线程爆炸测试 - 创建海量生产者协程
     */
    suspend fun testThreadApocalypse(): ApocalypseTestResult {
        println("=== 🧵 线程爆炸测试 ===")

        val processor = ChannelProcessor<String>(
            config = Config(
                channelCapacity = 1000,
                consumerCount = 10,
                shutdownTimeout = 60.seconds
            )
        )

        // 快速消费者
        processor.startConsumers { item ->
            // 几乎不处理，只计数
        }

        val startTime = System.currentTimeMillis()
        val successCount = AtomicLong(0)
        val errorCount = AtomicLong(0)

        // 创建10万个生产者协程！
        val producerCount = 100000
        println("创建 $producerCount 个生产者协程...")

        val producerJobs = List(producerCount) { producerId ->
            GlobalScope.launch {
                try {
                    // 每个生产者只生产1条消息
                    if (processor.produce("Producer-$producerId")) {
                        successCount.incrementAndGet()
                    } else {
                        errorCount.incrementAndGet()
                    }
                } catch (e: Exception) {
                    errorCount.incrementAndGet()
                }
            }
        }

        println("等待所有生产者完成...")
        producerJobs.forEach { it.join() }

        println("生产完成，等待消费...")
        delay(10000) // 给消费者时间处理

        val shutdownResult = processor.shutdown()
        val duration = System.currentTimeMillis() - startTime

        return ApocalypseTestResult(
            testName = "线程爆炸测试",
            producedBeforeCrash = successCount.get(),
            oomCount = errorCount.get(),
            duration = duration,
            shutdownResult = shutdownResult,
            survived = errorCount.get() < producerCount * 0.1 // 错误率低于10%算存活
        )
    }

    /**
     * 测试3: 僵尸消费者测试 - 消费者随机挂起或崩溃
     */
    suspend fun testZombieConsumers(): ApocalypseTestResult {
        println("=== 🧟 僵尸消费者测试 ===")

        val processor = ChannelProcessor<String>(
            config = Config(
                channelCapacity = 500,
                consumerCount = 20, // 很多消费者
                shutdownTimeout = 60.seconds
            )
        )

        val zombieCount = AtomicLong(0)
        val crashCount = AtomicLong(0)

        // 创建有问题的消费者
        processor.startConsumers { consumerId ->
            // 随机行为：正常处理、挂起、崩溃
            when ((0..100).random()) {
                in 0..70 -> {
                    // 70% 正常处理
                    delay(10)
                }
                in 71..90 -> {
                    // 20% 成为僵尸（永久挂起）
                    zombieCount.incrementAndGet()
                    println("🧟 消费者 $consumerId 变成僵尸!")
                    while (true) {
                        delay(1000) // 永久挂起
                    }
                }
                else -> {
                    // 10% 崩溃
                    crashCount.incrementAndGet()
                    println("💥 消费者 $consumerId 崩溃!")
                    throw RuntimeException("模拟消费者崩溃")
                }
            }
        }

        val startTime = System.currentTimeMillis()
        val producedCount = AtomicLong(0)

        // 持续生产
        val producerJob = GlobalScope.launch {
            var counter = 0L
            while (counter < 10000) {
                if (processor.produce("Item-$counter")) {
                    counter++
                    producedCount.set(counter)
                }
                delay(1)
            }
        }

        // 运行一段时间后强制关闭
        delay(30000)
        producerJob.cancel()

        val shutdownResult = processor.shutdownNow() // 强制关闭，因为有僵尸

        val duration = System.currentTimeMillis() - startTime

        return ApocalypseTestResult(
            testName = "僵尸消费者测试",
            producedBeforeCrash = producedCount.get(),
            oomCount = zombieCount.get() + crashCount.get(),
            duration = duration,
            shutdownResult = shutdownResult,
            survived = shutdownResult.success
        )
    }

    /**
     * 测试4: 时间扭曲测试 - 极端的时间相关边界条件
     */
    suspend fun testTimeWarp(): ApocalypseTestResult {
        println("=== ⏰ 时间扭曲测试 ===")

        val processor = ChannelProcessor<String>(
            config = Config(
                channelCapacity = 100,
                consumerCount = 4,
                produceTimeout = 1.milliseconds, // 极短超时
                shutdownTimeout = 1.milliseconds  // 极短关闭超时
            )
        )

        // 极慢消费者
        processor.startConsumers { item ->
            delay(1000) // 1秒处理时间，远大于生产超时
        }

        val startTime = System.currentTimeMillis()
        val timeoutCount = AtomicLong(0)
        val successCount = AtomicLong(0)

        // 快速生产，大部分会超时
        val producerJob = GlobalScope.launch {
            repeat(1000) { i ->
                if (processor.produceWithTimeout("Item-$i")) {
                    successCount.incrementAndGet()
                } else {
                    timeoutCount.incrementAndGet()
                }
                delay(1)
            }
        }

        producerJob.join()

        // 立即关闭，不给消费者时间处理
        val shutdownResult = processor.shutdown() // 使用1ms超时

        val duration = System.currentTimeMillis() - startTime

        return ApocalypseTestResult(
            testName = "时间扭曲测试",
            producedBeforeCrash = successCount.get(),
            oomCount = timeoutCount.get(),
            duration = duration,
            shutdownResult = shutdownResult,
            survived = true // 这个测试重点是验证边界行为，不要求完全成功
        )
    }

    /**
     * 测试5: 数据污染测试 - 发送各种异常数据
     */
    suspend fun testDataPollution(): ApocalypseTestResult {
        println("=== 🦠 数据污染测试 ===")

        val processor = ChannelProcessor<Any>( // 使用Any类型接收各种数据
            config = Config(
                channelCapacity = 1000,
                consumerCount = 8,
                shutdownTimeout = 60.seconds
            )
        )

        val exceptionCount = AtomicLong(0)

        // 消费者处理各种异常数据
        processor.startConsumers { item ->
            try {
                // 尝试各种危险操作
                when (item) {
                    is String -> item.length // 正常字符串
                    is Int -> item.toString() // 数字
                    is Exception -> throw item // 直接抛出异常
                    is Class<*> -> item.getDeclaredMethods() // 反射操作
                    null -> throw NullPointerException("收到null") // 空值
                    else -> {
                        // 其他未知类型
                        item.hashCode()
                    }
                }
            } catch (e: Exception) {
                exceptionCount.incrementAndGet()
                // 吞掉异常，继续处理
            }
        }

        val startTime = System.currentTimeMillis()

        // 发送各种危险数据
        val dangerousData = listOf(
            "正常字符串",
            null, // 空值
            RuntimeException("模拟异常"),
            42, // 数字
            String::class.java, // Class对象
            Object(), // 普通对象
            ByteArray(1024), // 大数组
            mapOf("key" to "value"), // 集合
            { println("Lambda") }, // 函数
            CharArray(100) { 'X' }, // 字符数组
            // 更多危险数据...
        )

        val producerJob = GlobalScope.launch {
            repeat(1000) { i ->
                val data = dangerousData[i % dangerousData.size]
                processor.produce(data!!)
                delay(10)
            }
        }

        producerJob.join()
        delay(5000) // 给消费者时间处理

        val shutdownResult = processor.shutdown()
        val duration = System.currentTimeMillis() - startTime

        return ApocalypseTestResult(
            testName = "数据污染测试",
            producedBeforeCrash = 1000,
            oomCount = exceptionCount.get(),
            duration = duration,
            shutdownResult = shutdownResult,
            survived = exceptionCount.get() < 500 // 异常少于50%算存活
        )
    }

    /**
     * 测试6: 资源枯竭测试 - 模拟系统资源耗尽
     */
    suspend fun testResourceExhaustion(): ApocalypseTestResult {
        println("=== ⚡ 资源枯竭测试 ===")

        // 创建大量处理器，耗尽资源
        val processors = mutableListOf<ChannelProcessor<String>>()
        val createdCount = AtomicLong(0)
        val oomCount = AtomicLong(0)

        val startTime = System.currentTimeMillis()

        try {
            while (true) {
                val processor = ChannelProcessor<String>(
                    config = Config(
                        channelCapacity = 1000,
                        consumerCount = 4
                    )
                )

                // 启动消费者
                processor.startConsumers { item ->
                    delay(10)
                }

                // 开始生产数据
                GlobalScope.launch {
                    repeat(1000) { i ->
                        processor.produce("ResourceTest-${createdCount.get()}-$i")
                        delay(1)
                    }
                }

                processors.add(processor)
                createdCount.incrementAndGet()

                if (createdCount.get() % 100 == 0L) {
                    val runtime = Runtime.getRuntime()
                    val usedMB = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024)
                    println("已创建 ${createdCount.get()} 个处理器, 内存使用: ${usedMB}MB")
                }
            }
        } catch (e: OutOfMemoryError) {
            oomCount.incrementAndGet()
            println("💥 资源耗尽! 创建了 ${createdCount.get()} 个处理器")
        } catch (e: Exception) {
            println("其他异常: ${e.message}")
        }

        // 尝试关闭所有处理器
        println("尝试关闭所有处理器...")
        var successfulShutdowns = 0
        processors.forEach { processor ->
            try {
                val result = processor.shutdownNow()
                if (result.success) successfulShutdowns++
            } catch (e: Exception) {
                println("关闭处理器时异常: ${e.message}")
            }
        }

        val duration = System.currentTimeMillis() - startTime

        return ApocalypseTestResult(
            testName = "资源枯竭测试",
            producedBeforeCrash = createdCount.get(),
            oomCount = oomCount.get(),
            duration = duration,
            shutdownResult = ShutdownResult(
                success = successfulShutdowns > createdCount.get() * 0.5, // 成功关闭一半以上
                remainingTasks = (createdCount.get() - successfulShutdowns).toInt(),
                shutdownDuration = duration
            ),
            survived = oomCount.get() == 0L
        )
    }
}

/**
 * 毁灭测试结果
 */
data class ApocalypseTestResult(
    val testName: String,
    val producedBeforeCrash: Long,
    val oomCount: Long,
    val duration: Long,
    val shutdownResult: ShutdownResult,
    val survived: Boolean
) {
    suspend fun printReport() {
        println("\n" + "☠️".repeat(70))
        println("☠️                    毁灭测试报告: $testName                    ☠️")
        println("☠️".repeat(70))
        println("运行时间: ${duration}ms")
        println("生产数量: $producedBeforeCrash")
        println("崩溃次数: $oomCount")
        println("存活状态: ${if (survived) "✅ 幸存" else "💀 被毁灭"}")
        println("关闭结果: ${shutdownResult.message}")
        println("☠️".repeat(70))
    }
}

/**
 * 修复版终极组合测试 - 解决Lambda中的挂起函数问题
 */
/**
 * 在 Kotlin 1.7.22 中绝对能工作的修复版本
 */
class UltimateDestructionTester {

    suspend fun runAllApocalypseTests(): DestructionSummary {
        println("🚀 启动终极毁灭测试套件...")

        val tester = DestructionLevelTester()
        val results = mutableListOf<ApocalypseTestResult>()

        // 修复：完全避免使用Lambda列表，直接逐个运行测试
//        runTest(1, "内存爆炸测试") { tester.testMemoryApocalypse() }?.let { results.add(it) }
        runTest(2, "线程爆炸测试") { tester.testThreadApocalypse() }?.let { results.add(it) }
        runTest(3, "僵尸消费者测试") { tester.testZombieConsumers() }?.let { results.add(it) }
        runTest(4, "时间扭曲测试") { tester.testTimeWarp() }?.let { results.add(it) }
        runTest(5, "数据污染测试") { tester.testDataPollution() }?.let { results.add(it) }
        runTest(6, "资源枯竭测试") { tester.testResourceExhaustion() }?.let { results.add(it) }

        return DestructionSummary(results)
    }

    /**
     * 辅助函数：运行单个测试
     */
    private suspend fun runTest(
        index: Int,
        testName: String,
        testBlock: suspend () -> ApocalypseTestResult
    ): ApocalypseTestResult? {
        println("\n" + "💣".repeat(50))
        println("💣          测试 $index/6: $testName           💣")
        println("💣".repeat(50))

        return try {
            val result = testBlock()
            result.printReport()
            result
        } catch (e: Exception) {
            println("💥 测试执行失败: ${e.message}")
            e.printStackTrace()
            ApocalypseTestResult(
                testName = testName,
                producedBeforeCrash = 0,
                oomCount = 1,
                duration = 0,
                shutdownResult = ShutdownResult(false, 0, 0),
                survived = false
            )
        } finally {
            // 测试间休息，让系统恢复
            if (index < 6) { // 最后一个测试后不需要延迟
                delay(5000)
                System.gc()
                println("系统恢复中...")
                delay(3000)
            }
        }
    }
}

/**
 * 替代方案：使用更简单的方法逐个运行测试
 */
class SimpleDestructionTester {

    suspend fun runAllTestsSimply(): DestructionSummary {
        println("🚀 启动简单版毁灭测试套件...")

        val tester = DestructionLevelTester()
        val results = mutableListOf<ApocalypseTestResult>()

        // 方法1：直接逐个调用，避免Lambda问题
        println("\n" + "💣".repeat(50))
        println("💣          测试 1/6: 内存爆炸测试           💣")
        println("💣".repeat(50))
        val result1 = tester.testMemoryApocalypse()
        results.add(result1)
        result1.printReport()
        delay(5000)

        println("\n" + "💣".repeat(50))
        println("💣          测试 2/6: 线程爆炸测试           💣")
        println("💣".repeat(50))
        val result2 = tester.testThreadApocalypse()
        results.add(result2)
        result2.printReport()
        delay(5000)

        println("\n" + "💣".repeat(50))
        println("💣          测试 3/6: 僵尸消费者测试           💣")
        println("💣".repeat(50))
        val result3 = tester.testZombieConsumers()
        results.add(result3)
        result3.printReport()
        delay(5000)

        println("\n" + "💣".repeat(50))
        println("💣          测试 4/6: 时间扭曲测试           💣")
        println("💣".repeat(50))
        val result4 = tester.testTimeWarp()
        results.add(result4)
        result4.printReport()
        delay(5000)

        println("\n" + "💣".repeat(50))
        println("💣          测试 5/6: 数据污染测试           💣")
        println("💣".repeat(50))
        val result5 = tester.testDataPollution()
        results.add(result5)
        result5.printReport()
        delay(5000)

        println("\n" + "💣".repeat(50))
        println("💣          测试 6/6: 资源枯竭测试           💣")
        println("💣".repeat(50))
        val result6 = tester.testResourceExhaustion()
        results.add(result6)
        result6.printReport()

        return DestructionSummary(results)
    }
}

/**
 * 终极修复：使用协程作用域管理所有测试
 */
class CoroutineScopeDestructionTester {
    private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())

    suspend fun runAllTestsWithScope(): DestructionSummary {
        println("🚀 启动协程作用域版毁灭测试套件...")

        val tester = DestructionLevelTester()
        val results = mutableListOf<ApocalypseTestResult>()

        // 使用 async 并发执行测试
        val test1 = scope.async { tester.testMemoryApocalypse() }
        val test2 = scope.async { tester.testThreadApocalypse() }
        val test3 = scope.async { tester.testZombieConsumers() }
        val test4 = scope.async { tester.testTimeWarp() }
        val test5 = scope.async { tester.testDataPollution() }
        val test6 = scope.async { tester.testResourceExhaustion() }

        // 收集所有结果
        val allResults = listOf(test1, test2, test3, test4, test5, test6)

        allResults.forEachIndexed { index, deferred ->
            try {
                println("\n" + "💣".repeat(50))
                println("💣          等待测试 ${index + 1}/${allResults.size} 完成           💣")
                println("💣".repeat(50))

                val result = deferred.await()
                results.add(result)
                result.printReport()

                // 测试间休息
                delay(3000)
                System.gc()
            } catch (e: Exception) {
                println("💥 测试 ${index + 1} 执行失败: ${e.message}")
                results.add(ApocalypseTestResult(
                    testName = "测试${index + 1}",
                    producedBeforeCrash = 0,
                    oomCount = 1,
                    duration = 0,
                    shutdownResult = ShutdownResult(false, 0, 0),
                    survived = false
                ))
            }
        }

        return DestructionSummary(results)
    }

    fun shutdown() {
        scope.cancel()
        println("测试器已关闭")
    }
}

/**
 * 运行终极毁灭测试 - 使用修复后的版本
 */
fun main() = runBlocking {
    println("警告：这些测试可能会消耗大量系统资源，甚至导致系统不稳定！")
    println("请在测试环境中运行，生产环境慎用！")
    println("5秒后开始测试...")
    delay(5000)

    // 选择其中一种测试器运行
    val tester = UltimateDestructionTester()  // 修复版
    // val tester = SimpleDestructionTester()  // 简单版
    // val tester = CoroutineScopeDestructionTester()  // 协程作用域版

    val summary = tester.runAllApocalypseTests()
    summary.printFinalReport()

    // 最终系统状态检查
    println("\n🧹 最终系统状态检查...")
    val runtime = Runtime.getRuntime()
    val usedMB = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024)
    val maxMB = runtime.maxMemory() / (1024 * 1024)
    println("内存使用: ${usedMB}MB / ${maxMB}MB")
    System.gc()
    delay(1000)
    val usedMBAfterGC = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024)
    println("垃圾回收后内存使用: ${usedMBAfterGC}MB")
    println("测试完成!")

    // 如果是协程作用域版，需要关闭
//    if (tester is CoroutineScopeDestructionTester) {
//        tester.shutdown()
//    }
}

/**
 * 最简版本 - 绝对没有Lambda问题
 */
fun simplestMain() = runBlocking {
    println("运行最简版测试...")

    val tester = DestructionLevelTester()
    val results = mutableListOf<ApocalypseTestResult>()

    // 最直接的方式，没有任何Lambda
    println("运行内存爆炸测试...")
    results.add(tester.testMemoryApocalypse())
    delay(3000)

    println("运行线程爆炸测试...")
    results.add(tester.testThreadApocalypse())
    delay(3000)

    println("运行数据污染测试...")
    results.add(tester.testDataPollution())

    val summary = DestructionSummary(results)
    summary.printFinalReport()
    println("最简测试完成!")
}

/**
 * 毁灭测试总结
 */
class DestructionSummary(private val results: List<ApocalypseTestResult>) {
    val totalTests: Int get() = results.size
    val survivedTests: Int get() = results.count { it.survived }
    val destructionRate: Double get() = (totalTests - survivedTests).toDouble() / totalTests

    fun printFinalReport() {
        println("\n" + "🎯".repeat(80))
        println("🎯                         终极毁灭测试总结                         🎯")
        println("🎯".repeat(80))

        results.forEachIndexed { index, result ->
            println("${index + 1}. ${result.testName}")
            println("   状态: ${if (result.survived) "✅ 幸存" else "💀 毁灭"}")
            println("   生产: ${result.producedBeforeCrash}")
            println("   崩溃: ${result.oomCount}")
            println("   关闭: ${if (result.shutdownResult.success) "成功" else "失败"}")
            println()
        }

        println("总体统计:")
        println("   总测试数: $totalTests")
        println("   幸存测试: $survivedTests")
        println("   毁灭率: ${"%.1f".format(destructionRate * 100)}%")
        println("   系统韧性: ${"%.1f".format((1 - destructionRate) * 100)}%")

        when {
            destructionRate == 0.0 -> println("🌟 系统坚不可摧！")
            destructionRate < 0.3 -> println("✅ 系统表现优秀")
            destructionRate < 0.7 -> println("⚠️  系统表现一般")
            else -> println("💀 系统需要重大改进")
        }

        println("🎯".repeat(80))
    }
}